/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pneuservis.backend.dao.impl;

import java.math.BigDecimal;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import pneuservis.backend.dao.TyreTypeDAOLocal;
import pneuservis.backend.others.Season;
import pneuservis.backend.entities.TyreType;

/**
 *
 * @author Admin
 */
@Stateless
public class TyreTypeDAO implements TyreTypeDAOLocal {

    @PersistenceContext
    private EntityManager entityManager;
    
    @Override
    public void createTyreType(TyreType tyreType) throws IllegalArgumentException {

        if (tyreType == null) {
            throw new IllegalArgumentException("tyreType cant be null");
        }

        if (tyreType.getId() != null) {
            throw new IllegalArgumentException("cannot create tyre with id null");
        }

        validate(tyreType);

        entityManager.persist(tyreType);
    }

    @Override
    public TyreType getTyreType(Long id) throws IllegalArgumentException {
        if (id == null) {
            throw new IllegalArgumentException("tyre id is null");
        }

        TyreType tyreType = entityManager.find(TyreType.class, id);
        if(tyreType == null){
            return null;
        }
        entityManager.detach(tyreType);
        return tyreType;
    }

    @Override
    public void updateTyreType(TyreType tyreType) throws IllegalArgumentException {
        if (tyreType == null) {
            throw new IllegalArgumentException("tyre is null, cannot update");
        }

        if (tyreType.getId() == null) {
            throw new IllegalArgumentException("tyres id is null");
        }

        validate(tyreType);
        TyreType tyre = entityManager.find(TyreType.class, tyreType.getId());

        if (tyre == null) {
            throw new IllegalArgumentException("no tyre to update");
        }
        entityManager.detach(tyre);
        entityManager.merge(tyreType);
        
    }

    @Override
    public void removeTyreType(TyreType tyreType) throws IllegalArgumentException {
        if (tyreType == null) {
            throw new IllegalArgumentException("tyre is null");
        }

        if (tyreType.getId() == null) {
            throw new IllegalArgumentException("tyre id is null");
        }

        TyreType tyre = entityManager.find(TyreType.class, tyreType.getId());

        if (tyre == null) {
            throw new IllegalArgumentException("there is no tyre to remove");
        }

        entityManager.remove(tyre);

    }

    @Override
    public List<TyreType> getAllTyreTypes() {

        List<TyreType> tyreList;
        Query query = entityManager.createQuery("SELECT p FROM TyreType p ORDER BY p.id");

        tyreList = query.getResultList();
        for (TyreType t : tyreList){
            entityManager.detach(t);
        }
        return tyreList;
    }

    @Override
    public List<TyreType> findTyresByRimSize(int rimSize) throws IllegalArgumentException {
        if (rimSize <= 0) {
            throw new IllegalArgumentException("rimsize is with wrong value");
        }

        List<TyreType> tyreList;
        Query query = entityManager.createQuery("SELECT p FROM TyreType p WHERE p.rimSize = :rimSize");
        query.setParameter("rimSize", rimSize);

        tyreList = query.getResultList();
        for (TyreType t : tyreList){
            entityManager.detach(t);
        }

        return tyreList;
    }

    @Override
    public List<TyreType> findTyresByWidth(int width) throws IllegalArgumentException {
        if (width <= 0) {
            throw new IllegalArgumentException("width is with wrong value");
        }

        List<TyreType> tyreList;
        Query query = entityManager.createQuery("SELECT p FROM TyreType p WHERE p.width = :width");
        query.setParameter("width", width);

        tyreList = query.getResultList();
        for (TyreType t : tyreList){
            entityManager.detach(t);
        }

        return tyreList;
    }
    
    @Override
    public List<TyreType> findTyresByProfile(int profile) throws IllegalArgumentException {
        if (profile <= 0) {
            throw new IllegalArgumentException("profile is with wrong value");
        }

        List<TyreType> tyreList;
        Query query = entityManager.createQuery("SELECT p FROM TyreType p WHERE p.profile = :profile");
        query.setParameter("profile", profile);

        tyreList = query.getResultList();
        for (TyreType t : tyreList){
            entityManager.detach(t);
        }

        return tyreList;
    }

    @Override
    public List<TyreType> findTyresBySeason(Season season) throws IllegalArgumentException {
        if (season == null) {
            throw new IllegalArgumentException("season cant be null");
        }

        List<TyreType> tyreList;
        Query query = entityManager.createQuery("SELECT p FROM TyreType p WHERE p.season = :season");
        query.setParameter("season", season);

        tyreList = query.getResultList();
        for (TyreType t : tyreList){
            entityManager.detach(t);
        }

        return tyreList;
    }

    @Override
    public List<TyreType> findTyresByManufacturer(String manufacturer) {
        if (manufacturer == null) {
            throw new IllegalArgumentException("manufacturer cant be null");
        }

        List<TyreType> tyreList;
        Query query = entityManager.createQuery("SELECT p FROM TyreType p WHERE p.manufacturer = :manufacturer");
        query.setParameter("manufacturer", manufacturer);

        tyreList = query.getResultList();
        for (TyreType t : tyreList){
            entityManager.detach(t);
        }

        return tyreList;
    }

    private void validate(TyreType tyreType) {
        if (tyreType == null) {
            throw new IllegalArgumentException("tyreType cannot be null");
        }
        if (tyreType.getPrice() == null || tyreType.getPrice().compareTo(BigDecimal.ZERO) < 0) {
            throw new IllegalArgumentException("tyreType.price");
        }
        if (tyreType.getProfile() <= 0) {
            throw new IllegalArgumentException("Profile can't be negative or 0.");
        }
        if (tyreType.getRimSize() <= 0) {
            throw new IllegalArgumentException("RimSize can't be negative or 0.");
        }
        if (tyreType.getWidth() <= 0) {
            throw new IllegalArgumentException("Profile can't be negative or 0.");
        }
        if (tyreType.getSeason() == null) {
            throw new IllegalArgumentException("Season can't be null.");
        }
        if (tyreType.getManufacturer() == null) {
            throw new IllegalArgumentException("Manufacturer can't be null.");
        }
        if (tyreType.getManufacturer().trim().isEmpty()) {
            throw new IllegalArgumentException("Manufacturer must be a valid name.");
        }
    }
}
